package com.santoker.user.service.service.biz.message.impl;

import com.santoker.baseservice.ApiResponseBody;
import com.santoker.baseservice.ApiResponseCode;
import com.santoker.baseservice.constant.GlobalConstant;
import com.santoker.baseservice.enums.AccountTypeEnum;
import com.santoker.baseservice.util.Generator;
import com.santoker.user.service.exception.CommonServiceException;
import com.santoker.user.service.model.User;
import com.santoker.user.service.service.biz.message.MessageService;
import com.santoker.user.service.service.common.IUserService;
import com.santoker.user.service.service.common.RedisService;
import com.santoker.user.service.service.tp.mail.MailService;
import com.santoker.user.service.service.tp.mail.MailVo;
import com.santoker.user.service.service.tp.submail.MessageApi;
import com.santoker.user.service.service.tp.submail.MessageVars;
import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Objects;

@Slf4j
@Service
public class MessageServiceImpl implements MessageService {

    @Autowired
    private RedisService redisService;
    @Autowired
    private MessageApi messageApi;
    @Autowired
    private MailService mailService;
    @Autowired
    private IUserService iUserService;

    @Override
    public void sendCaptchaMessage(String mobile) {

        log.info("------------------------------ 发送国内短信验证码  ------------------------------");
        ApiResponseBody.printRequestParam(mobile);

        String code = Generator.generateCaptchaCode();

        // 验证手机号是否已注册
        User userByMobile = iUserService.getUserByMobile(mobile);
        if (Objects.nonNull(userByMobile)) {
            throw new CommonServiceException(ApiResponseCode.REGISTER_DUPLICATED_PHONE);
        }

        // 发送短信验证码
        sendSmsCode(AccountTypeEnum.MOBILE_1.getKey(), mobile, code);

        redisService.setAuthCode(mobile, code, GlobalConstant.CODE_VALID_DURATION);
    }

    @Override
    public void sendInternetionCaptchaMessage(String mobile) {

        log.info("------------------------------ 发送国际短信验证码  ------------------------------");
        ApiResponseBody.printRequestParam(mobile);

        String code = Generator.generateCaptchaCode();

        // 验证手机号是否已注册
        User userByMobile = iUserService.getUserByMobile(mobile);
        if (Objects.nonNull(userByMobile)) {
            throw new CommonServiceException(ApiResponseCode.REGISTER_DUPLICATED_PHONE);
        }

        // 发送短信验证码
        sendSmsCode(AccountTypeEnum.MOBILE_2.getKey(), mobile, code);

        redisService.setAuthCode(mobile, code, GlobalConstant.CODE_VALID_DURATION);
    }

    @Override
    public void sendEmailCaptchaMessage(String email) {

        log.info("------------------------------ 发送邮箱验证码  ------------------------------");
        ApiResponseBody.printRequestParam(email);

        String code = Generator.generateCaptchaCode();

        // 验证邮箱是否已注册
        User userByEmail = iUserService.getUserByEmail(email);
        if (Objects.nonNull(userByEmail)) {
            throw new CommonServiceException(ApiResponseCode.REGISTER_DUPLICATED_EMAIL);
        }

        // 发送邮箱验证码
        sendEmailCode(email, code);

        redisService.setAuthCode(email, code, GlobalConstant.CODE_VALID_DURATION);
    }

    @Override
    public void getAccountCaptcha(Integer accountType, String account) {

        log.info("------------------------------ 发送账号验证码  ------------------------------");
        ApiResponseBody.printRequestParam(accountType, account);

        String code = Generator.generateCaptchaCode();

        // 发送邮箱验证码
        if (Objects.equals(AccountTypeEnum.EMAIL.getKey(), accountType)) {
            sendEmailCode(account, code);
        }
        // 发送短信验证码
        else {
            sendSmsCode(accountType, account, code);
        }

        redisService.setAuthCode(account, code, GlobalConstant.CODE_VALID_DURATION);
    }

    private void sendSmsCode(int mobileType, String mobile, String code) {
        long expire = redisService.getAuthCodeExpire(mobile);
        log.info("expire : {}", expire);

        if (expire > (GlobalConstant.CODE_VALID_DURATION - GlobalConstant.CODE_SEND_GAP)) {
            throw new CommonServiceException(ApiResponseCode.CODE_EXPIRED);
        }

        MessageVars vars = MessageVars.builder()
                .mobile(mobile)
                .code(code)
                .build();

        SendSmsResponse sendSmsResponse;

        // 国内短信
        if (Objects.equals(AccountTypeEnum.MOBILE_1.getKey(), mobileType)) {
            sendSmsResponse = messageApi.sendMessage(vars);
        }
        // 国际短信
        else {
            sendSmsResponse = messageApi.sendInternationalMessage(vars);
        }

        if (Objects.isNull(sendSmsResponse)) {
            throw new CommonServiceException(ApiResponseCode.SEND_MOBILE_CODE_FAILURE);
        }

        // 输出 JSON 格式的字符串回包
        log.info(SendSmsResponse.toJsonString(sendSmsResponse));

        // 可以取出单个值，您可以通过官网接口文档或跳转到 response 对象的定义处查看返回字段的定义
        log.info(sendSmsResponse.getRequestId());

        if (sendSmsResponse.getSendStatusSet().length == 0 ||
                !sendSmsResponse.getSendStatusSet()[0].getCode().equals("Ok")) {
            throw new CommonServiceException(ApiResponseCode.SEND_MOBILE_CODE_FAILURE);
        }
    }

    private void sendEmailCode(String email, String code) {
        long expire = redisService.getAuthCodeExpire(email);
        log.info("expire : {}", expire);

        if (expire > (GlobalConstant.CODE_VALID_DURATION - GlobalConstant.CODE_SEND_GAP)) {
            throw new CommonServiceException(ApiResponseCode.CODE_EXPIRED);
        }

        MailVo mailVo = new MailVo();
        mailVo.setTo(email);
        mailVo.setSubject("Verification Code ");
        mailVo.setText(new StringBuffer().append("Verification Code: ").append(code)
                .append(", Please input in 5 Minutes").toString());
        mailVo = mailService.sendMail(mailVo);
        log.info("发送邮箱验证码，请求结果：{}", mailVo);

        if (!mailVo.isSuccess()) {
            throw new CommonServiceException(ApiResponseCode.SEND_EMAIL_CODE_FAILURE.getCode(), mailVo.getError());
        }
    }

}
